package cn.sh.library.mgts.framework.handler;

import java.net.ConnectException;
import java.sql.SQLException;

import javax.servlet.http.HttpServletRequest;

import org.apache.ibatis.binding.BindingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.server.MethodNotAllowedException;
import org.springframework.web.servlet.NoHandlerFoundException;

import cn.sh.library.mgts.base.ResponseCodeEnums;
import cn.sh.library.mgts.bean.ResponseBean;
import cn.sh.library.mgts.framework.exception.CustomRuntimeException;

@RestControllerAdvice(annotations = { RestController.class, Controller.class })
public class ResponseExceptionHandle {

	private static final Logger logger = LoggerFactory.getLogger(ResponseExceptionHandle.class);

	@ExceptionHandler(value = { BindException.class })
	@ResponseBody
	@ResponseStatus(value = HttpStatus.BAD_REQUEST)
	public ResponseBean<String> badRequest(BindException e) {
		logger.error("occurs error when execute method ,message {}", e.getMessage());
		logger.error("", e);
		return new ResponseBean<>(false, ResponseCodeEnums.BAD_REQUEST);
	}

	/**
	 * 404错误异常的捕获
	 * 
	 * @param e
	 * @return
	 */
	@ExceptionHandler(value = {NoHandlerFoundException.class })
	@ResponseBody
	@ResponseStatus(value = HttpStatus.NOT_FOUND)
	public ResponseBean<String> badRequestNotFound(BindException e) {
		logger.error("occurs error when execute method ,message {}", e.getMessage());
		logger.error("", e);
		return new ResponseBean<>(false, null, ResponseCodeEnums.NOT_FOUND);
	}

	/**
	 * mybatis未绑定异常
	 * 
	 * @param e
	 * @return
	 */
	@ExceptionHandler(BindingException.class)
	@ResponseBody
	@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
	public ResponseBean<String> mybatis(Exception e) {
		logger.error("occurs error when execute method ,message {}", e.getMessage());
		logger.error("", e);
		return new ResponseBean<>(false, ResponseCodeEnums.SERVER_ERROR);
	}

	/**
	 * 自定义异常的捕获 自定义抛出异常。统一的在这里捕获返回JSON格式的友好提示。
	 * 
	 * @param exception
	 * @param request
	 * @return
	 */
	@ExceptionHandler(value = {CustomRuntimeException.class })
	@ResponseBody
	@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
	public <T> ResponseBean<T> sendError(CustomRuntimeException exception, HttpServletRequest request) {
		String requestURI = request.getRequestURI();
		logger.error("occurs error when execute url ={} ,message {}", requestURI, exception.getMsg());
		logger.error("", exception);
		return new ResponseBean<>(false, exception.getCode(), exception.getMsg());
	}

	/**
	 * 数据库操作出现异常
	 * 
	 * @param e
	 * @return
	 */
	@ExceptionHandler(value = {SQLException.class, DataAccessException.class })
	@ResponseBody
	@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
	public ResponseBean<String> systemError(Exception e) {
		logger.error("occurs error when execute method ,message {}", e.getMessage());
		logger.error("", e);
		return new ResponseBean<>(false, ResponseCodeEnums.DATABASE_ERROR);
	}

	/**
	 * 网络连接失败！
	 * 
	 * @param e
	 * @return
	 */
	@ExceptionHandler(value = {ConnectException.class })
	@ResponseBody
	@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
	public ResponseBean<String> connect(Exception e) {
		logger.error("occurs error when execute method ,message {}", e.getMessage());
		logger.error("", e);
		return new ResponseBean<>(false, ResponseCodeEnums.CONNECTION_ERROR);
	}

	@ExceptionHandler(value = {Exception.class })
	@ResponseBody
	@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
	public ResponseBean<String> sysError(Exception e) {
		logger.error("occurs error when execute method ,message {}", e.getMessage());
		logger.error("", e);
		return new ResponseBean<>(false, ResponseCodeEnums.SERVER_ERROR);
	}

	@ExceptionHandler(value = {MethodNotAllowedException.class })
	@ResponseBody
	@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
	public ResponseBean<String> notAllowed(Exception e) {
		logger.error("occurs error when execute method ,message {}", e.getMessage());
		logger.error("", e);
		return new ResponseBean<>(false, ResponseCodeEnums.SERVER_ERROR);
	}

}
